package cn.zyjw.service.impl;

import cn.zyjw.feign.OAuth2FeignClient;
import cn.zyjw.geet.GeetestLib;
import cn.zyjw.model.JwtToken;
import cn.zyjw.model.LoginForm;
import cn.zyjw.model.LoginUser;
import cn.zyjw.service.LoginService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import feign.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {


    @Autowired
    private OAuth2FeignClient oAuth2FeignClient;

    @Value("${basic.token:Basic Y29pbi1hcGk6Y29pbi1zZWNyZXQ=}")
    private String clientToken;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private GeetestLib geetestLib;

    /**
     * 用户登录
     *
     * @param loginForm
     * @return
     */
    @Override
    public LoginUser login(LoginForm loginForm) {
        log.info("登录开始:{}", loginForm);
        checkFormData(loginForm);
        //登录换取token
        //调用oAuth2FeignClient 换取用户token
        Response response = oAuth2FeignClient.getJwtToken("password", loginForm.getUsername(), loginForm.getPassword(), "member_type", clientToken);
        if (response == null) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        String body = response.body().toString();
        JSONObject bodyJson = JSON.parseObject(body);
        if (response.status() == 400) {
            throw new ApiException(bodyJson.getString("error_description"));
        } else if (response.status() != 200) {
            throw new ApiException(ApiErrorCode.FAILED);
        }
        JwtToken jwtToken = JSONObject.parseObject(body, JwtToken.class);
        //token 放入redis 用于网关验证
        String accessToken = jwtToken.getAccessToken();
        redisTemplate.opsForValue().set(accessToken, "", jwtToken.getExpiresIn(), TimeUnit.SECONDS);
        return new LoginUser(loginForm.getUsername(), jwtToken.getExpiresIn(), "bearer " + accessToken, jwtToken.getRefreshToken());
    }

    /**
     * 校验数据
     * 极验证的数据校验
     *
     * @param loginForm
     */
    private void checkFormData(LoginForm loginForm) {
        loginForm.check(geetestLib, redisTemplate);
    }
}
